package com.xiaojian.blog.service.impl;

import com.github.pagehelper.PageHelper;
import com.xiaojian.blog.constant.WebConstant;
import com.xiaojian.blog.controller.admin.AttachController;
import com.xiaojian.blog.dao.AttachPOMapper;
import com.xiaojian.blog.dao.CommentPOMapper;
import com.xiaojian.blog.dao.ContentPOMapper;
import com.xiaojian.blog.dao.MetaPOMapper;
import com.xiaojian.blog.dto.MetaDto;
import com.xiaojian.blog.dto.Types;
import com.xiaojian.blog.exception.TipException;
import com.xiaojian.blog.model.*;
import com.xiaojian.blog.model.VO.ArchiveVO;
import com.xiaojian.blog.model.VO.BackResponseVO;
import com.xiaojian.blog.model.VO.StatisticsVO;
import com.xiaojian.blog.service.SiteService;

import com.xiaojian.blog.utils.DateKit;
import com.xiaojian.blog.utils.TaleUtils;
import com.xiaojian.blog.utils.ZipUtils;
import com.xiaojian.blog.utils.backup.Backup;
import javafx.scene.layout.TilePane;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.support.SimpleTriggerContext;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.print.DocFlavor;
import java.awt.image.ImagingOpException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.*;

@Service
public class SiteServiceImpl implements SiteService {

    private static final Logger LOGGER = LoggerFactory.getLogger(SiteServiceImpl.class);

    @Resource
    private CommentPOMapper commentPOMapper;

    @Resource
    private ContentPOMapper contentPOMapper;

    @Resource
    private AttachPOMapper attachPOMapper;

    @Resource
    private MetaPOMapper metaPOMapper;

    @Override//最新收到的评论(将评论时间降序排列然后分页返回)
    public List<CommentPO> recentComments(int limit) {
        LOGGER.debug("Enter recentComments method:limit={}", limit);
        if (limit < 0 || limit > 10) {
            limit = 10;
        }
        CommentPOExample example = new CommentPOExample();
        example.setOrderByClause("created desc");
        PageHelper.startPage(1, limit);
        List<CommentPO> byPage = commentPOMapper.selectByExampleWithBLOBs(example);
        LOGGER.debug("Exit recentComments method");
        return byPage;
    }

    @Override//最新发表的文章
    public List<ContentPO> recentContents(int limit) {
        LOGGER.debug("Enter recentCOntents method");
        if (limit < 0 || limit > 10) {
            limit = 10;
        }
        ContentPOExample example = new ContentPOExample();
        example.createCriteria().andStatusEqualTo(Types.PUBLISH.getType())
                .andTypeEqualTo(Types.ARTICLE.getType());
        example.setOrderByClause("created desc");
        PageHelper.startPage(1, limit);
        List<ContentPO> list = contentPOMapper.selectByExample(example);
        LOGGER.debug("Exit recentCOntents method!");
        return list;
    }

    @Override//查询一条评论
    public CommentPO getComment(Integer coid) {
        if (null != coid) {
            return commentPOMapper.selectByPrimaryKey(coid);
        }
        return null;
    }

    /**
     * 系统备份
     * @param bk_type
     * @param bk_path
     * @param fmt
     * @return
     * @throws Exception
     */
    @Override
    public BackResponseVO backup(String bk_type, String bk_path, String fmt) throws Exception {
        BackResponseVO backResponse = new BackResponseVO();
        if (bk_type.equals("attach")) {
            if (StringUtils.isBlank(bk_path)) {
                throw new TipException("请输入备份文件存储路径");
            }
            if (!(new File(bk_path)).isDirectory()) {
                throw new TipException("请输入一个存在的目录");
            }
            String bkAttachDir = AttachController.CLASSPATH + "upload";
            String bkThemesDir = AttachController.CLASSPATH + "templates/themes";

            String fname = DateKit.dateFormat(new Date(), fmt)
                    + "_" + TaleUtils.getRandomNumber(5) + ".zip";

            String attachPath = bk_path + "/" + "attachs_" + fname;
            String themesPath = bk_path + "/" + "themes_" + fname;

            ZipUtils.zipFolder(bkAttachDir, attachPath);
            ZipUtils.zipFolder(bkThemesDir, themesPath);

            backResponse.setAttachPath(attachPath);
            backResponse.setThemePath(themesPath);
        }
        if (bk_type.equals("db")) {
            String bkAttachDir = AttachController.CLASSPATH + "upload/";
            if (!(new File(bkAttachDir)).isDirectory()) {
                File file = new File(bkAttachDir);
                if (!file.exists()) {
                    file.mkdirs();
                }
            }
            String sqlFileName = "tale_" + DateKit.dateFormat(new Date(), fmt)
                    + "_" + TaleUtils.getRandomNumber(5) + ".sql";
            String zipFile = sqlFileName.replace(".sql", ".zip");

            Backup backup = new Backup(TaleUtils.getNewDataSource().getConnection());
            String sqlContent = backup.execute();

            File sqlFile = new File(bkAttachDir);
            write(sqlContent, sqlFile, Charset.forName("UTF-8"));

            String zip = bkAttachDir + zipFile;
            ZipUtils.zipFile(sqlFile.getPath(), zip);

            if (!sqlFile.exists()) {
                throw new TipException("数据库备份失败");
            }
            sqlFile.delete();

            backResponse.setSqlPath(zipFile);

            //10秒后删除备份文件
            new Timer().schedule(new TimerTask() {
                @Override
                public void run() {
                    new File(zip).delete();
                }
            }, 10 * 1000);
        }
        return backResponse;
    }

    @Override//获取统计数据
    public StatisticsVO getStatistics() {
        LOGGER.debug("Enter getStatistics method");
        StatisticsVO statisticsVO = new StatisticsVO();

        ContentPOExample contentPOExample = new ContentPOExample();
        contentPOExample.createCriteria().andTypeEqualTo(Types.ARTICLE.getType())
                .andStatusEqualTo(Types.PUBLISH.getType());
        int articles = contentPOMapper.countByExample(contentPOExample);

        int comments = commentPOMapper.countByExample(new CommentPOExample());

        int attachs = attachPOMapper.countByExample(new AttachPOExample());

        MetaPOExample metaPOExample = new MetaPOExample();
        metaPOExample.createCriteria().andTypeEqualTo(Types.LINK.getType());
        int links = metaPOMapper.countByExample(metaPOExample);

        statisticsVO.setArticles((long)articles);
        statisticsVO.setComments((long)comments);
        statisticsVO.setAttachs((long)attachs);
        statisticsVO.setLinks((long)links);
        LOGGER.debug("Exit getStatistics method");
        return statisticsVO;
    }

    @Override//归档
    public List<ArchiveVO> getArchives() {
        LOGGER.debug("Enter getArchives method");
        List<ArchiveVO> archives = contentPOMapper.findReturnArchiveVO();
        if (null != archives) {
            archives.forEach(archive -> {
                ContentPOExample contentPOExample = new ContentPOExample();
                ContentPOExample.Criteria criteria = contentPOExample.createCriteria().andTypeEqualTo(Types.ARTICLE.getType())
                        .andStatusEqualTo(Types.PUBLISH.getType());
                contentPOExample.setOrderByClause("created desc");
                String date = archive.getDate();
                Date sd = DateKit.dateFormat(date, "yyyy年MM月");
                int start = DateKit.getUnixTimeByDate(sd);
                int end = DateKit.getUnixTimeByDate(DateKit.dateAdd(DateKit.INTERVAL_MONTH, sd, 1)) - 1;
                criteria.andCreatedGreaterThan(start);
                criteria.andCreatedLessThan(end);
                List<ContentPO> contentsList = contentPOMapper.selectByExample(contentPOExample);
                archive.setArticles(contentsList);
            });
        }
        LOGGER.debug("Exit getArchives method");
        return archives;
    }

    @Override
    public List<MetaDto> metas(String type, String orderBy, int limit) {
        LOGGER.debug("Enter metas method:type={},order={},limit={}", type, orderBy, limit);
        List<MetaDto> retList = null;
        if (StringUtils.isNotBlank(type)) {
            if (StringUtils.isBlank(orderBy)) {
                orderBy = "count desc, a.mid desc";
            }
            if (limit < 1 || limit > WebConstant.MAX_POSTS) {
                limit = 10;
            }
            Map<String, Object> paramap = new HashMap<>();
            paramap.put("type", type);
            paramap.put("order", orderBy);
            paramap.put("limit", limit);
            retList = metaPOMapper.selectFromSql(paramap);
        }
        LOGGER.debug("Exit metas method");
        return retList;
    }

    private void write(String date, File file, Charset charset) {
        FileOutputStream os = null;
        try{
            os = new FileOutputStream(file);
            os.write(date.getBytes(charset));
        } catch(IOException var8) {
            throw new IllegalStateException(var8);
        } finally {
            if (null != os) {
                try {
                    os.close();
                } catch(IOException var2) {
                    var2.printStackTrace();
                }
            }
        }
    }
}
